// services/uploadService.js
const UploadModel = require('../models/uploadModel')
const fs = require('fs-extra')
const path = require('path')
const dayjs = require('dayjs')
// const stream = require('stream')
class UploadService {
  async saveUploadFile(fileData) {
    const uploadRecord = new UploadModel({
      originalFilename: fileData.originalFilename,
      mimetype: fileData.mimetype,
      path: fileData.path,
      size: fileData.size
    })
    const savedRecord = await uploadRecord.save()
    return savedRecord
  }
  // 一个简单的函数来存储分片信息
  async storeChunkInfo(chunkPath, chunkName) {
    // 更复杂的实现会考虑校验等因素
    const chunksPath = path.resolve(__dirname, '../bigfileUploads/chunks')
    await fs.ensureDir(chunksPath) // 确保该文件夹存在
    const chunkFilePath = path.resolve(chunksPath, chunkName)
    const chunk = await fs.readFile(chunkPath)
    await fs.writeFile(chunkFilePath, chunk)
    // 删除分片文件
    await fs.remove(chunkPath)
    return chunkFilePath
  }
  // 假设你的服务器存储了分片信息，下面是一个简单的合并文件的函数
  async combineChunks(chunksPath, fileName, chunks) {
    const filePath = path.resolve(__dirname, '../bigfileUploads', fileName)
    await fs.ensureDir(path.dirname(filePath))

    // 创建一个空的文件
    await fs.writeFile(filePath, '')
    // 按顺序合并文件
    for (let i = 1; i <= chunks; i++) {
      // 分片名与上传时一致
      const chunkPath = path.resolve(chunksPath, `chunk-${fileName}-${i}`)
      // 读取分片内容并追加到文件中
      const data = await fs.readFile(chunkPath)
      await fs.appendFile(filePath, data)
      // 删除分片文件
      await fs.remove(chunkPath)
    }
    return filePath
  }

  // async combineSSE(ctx) {
  //   const { name, chunks } = ctx.query

  //   if (!name || !chunks) {
  //     ctx.status = 400
  //     ctx.body = { status: false, message: '合并参数不正确' }
  //     return
  //   }

  //   try {
  //     // 创建一个PassThrough流
  //     const passThrough = new stream.PassThrough()
  //     // 设置必要的SSE头部信息
  //     ctx.set({
  //       'Content-Type': 'text/event-stream', // 设置内容类型为SSE
  //       Connection: 'keep-alive', // 保持连接
  //       'Cache-Control': 'no-cache' // 禁用缓存
  //     })
  //     // 将PassThrough流绑定到Koa的响应体
  //     ctx.body = passThrough
  //     // 发送数据的函数
  //     const chunksPath = path.resolve(__dirname, '../bigfileUploads/chunks')
  //     const filePath = path.resolve(__dirname, '../bigfileUploads', name)
  //     await fs.ensureDir(path.dirname(filePath))
  //     // 创建一个空的文件
  //     await fs.writeFile(filePath, '')
  //     // 发送数据的函数
  //     const sendData = data => {
  //       passThrough.write(`data: ${JSON.stringify(data)}\n\n`)
  //     }
  //     let percent = 0
  //     // 按顺序合并文件
  //     for (let i = 1; i <= chunks; i++) {
  //       // 分片名与上传时一致
  //       const chunkPath = path.resolve(chunksPath, `chunk-${name}-${i}`)
  //       // 读取分片内容并追加到文件中
  //       const data = await fs.readFile(chunkPath)
  //       await fs.appendFile(filePath, data)
  //       // 删除分片文件
  //       await fs.remove(chunkPath)
  //       percent = Math.ceil((i / chunks) * 100)
  //       setImmediate(() => {
  //         sendData({
  //           status: false,
  //           data: percent
  //         })
  //       })
  //     }

  //     // 获取存储在临时目录中的文件信息
  //     const fileData = {
  //       originalFilename: name,
  //       mimetype: 'bigFile',
  //       path: filePath,
  //       size: -1
  //     }
  //     const savedFile = await this.saveUploadFile(fileData)
  //     setImmediate(() => {
  //       sendData({
  //         status: true,
  //         data: savedFile
  //       })
  //     })
  //     // passThrough.end()
  //     // 监听请求关闭事件，清理资源
  //     ctx.req.on('close', () => {
  //       console.log('前端主动关闭请求')
  //       passThrough.end()
  //     })
  //   } catch (error) {
  //     console.error('合并分片出错:', error)
  //     ctx.status = 400
  //     ctx.body = { status: false, message: '合并分片出错' }
  //   }
  // }
  async checkExistence(name) {
    // 判断是否已经上传过同名文件
    const result = await UploadModel.findOne({ originalFilename: name })
    return result
  }

  async merge(name, chunks, mergeStatus, taskId) {
    const chunksPath = path.resolve(__dirname, '../bigfileUploads/chunks')
    const filePath = path.resolve(__dirname, '../bigfileUploads', name)
    await fs.ensureDir(path.dirname(filePath))

    // 创建一个空的文件
    await fs.writeFile(filePath, '')
    // 按顺序合并文件
    for (let i = 1; i <= chunks; i++) {
      // 分片名与上传时一致
      const chunkPath = path.resolve(chunksPath, `chunk-${name}-${i}`)
      // 读取分片内容并追加到文件中
      const data = await fs.readFile(chunkPath)
      await fs.appendFile(filePath, data)
      // 删除分片文件
      await fs.remove(chunkPath)
      // 更新合并进度
      mergeStatus.set(taskId, {
        status: false,
        data: Math.ceil((i / chunks) * 100)
      })
    }

    // 获取存储在临时目录中的文件信息
    const uploadRecord = new UploadModel({
      originalFilename: name,
      mimetype: 'bigFile',
      path: filePath,
      size: -1
    })
    const savedRecord = await uploadRecord.save()
    // 标记合并完成
    mergeStatus.set(taskId, { status: true, data: savedRecord })
  }
  async getBigfiles() {
    // 指定文件夹路径
    const directoryPath = path.join(__dirname, '../bigfileUploads')
    try {
      // 读取指定目录下的所有文件
      const files = await fs.readdir(directoryPath)
      // 过滤出.zip文件
      const zipFiles = files.filter(
        file => path.extname(file).toLowerCase() === '.zip'
      )
      const filesDetails = await Promise.all(
        zipFiles.map(async file => {
          const filePath = path.join(directoryPath, file)
          const stat = await fs.stat(filePath)
          return {
            name: file,
            size: (stat.size / (1024 * 1024)).toFixed(2), // 文件大小（以字节为单位）
            createdAt: dayjs(stat.birthtime).format('YYYY-MM-DD HH:mm:ss'), // 文件创建时间
            // 其他你需要的属性
            filePath: filePath
          }
        })
      )

      return filesDetails
      // return zipFiles
    } catch (err) {
      throw new HttpError(err.message, 400)
    }
  }
}
module.exports = new UploadService()
